![]() |
![]() |
|
Wird dem Aufruf des Indexers ein Vereinsname übergeben, muss geprüft werden, an welcher Position sich dieser in der Tabelle, genau genommen also im Array, befindet. Hier hilft uns die statische Methode IndexOf der Klasse Array weiter. Dieser wird im ersten Parameter der Bezeichner des Arrays übergeben, im zweiten Parameter das gesuchte Element. Wird das Element nicht im Array gefunden, lautet der Rückgabewert –1, ansonsten ist es die Indexposition. Die Klasse Tabelle ist sehr flexibel. Sie gestattet es, beispielsweise mit
die aktuelle Platzierung des genannten Vereins abzufragen oder durch Übergabe eines int zu erfahren, welcher Verein sich auf dem entsprechenden Tabellenplatz befindet:
Ähnlich einfach könnte ein Verein auch nach Belieben zum Tabellenführer erklärt werden:
oder
Dass dabei der ursprüngliche Tabellenführer »verloren« geht, registrieren wir nur nebenbei. Selbstverständlich könnten wir Code schreiben, der alle Vereine dann um jeweils eine Position in der Tabelle verschiebt. Ehe wir uns aber diese Mühe machen, verrate ich Ihnen schon an dieser Stelle, dass es dazu ähnlich wie Arrays agierende Klassen im .NET Framework gibt, die genau dieses Verhalten zeigen: die Collections, auch als Auflistungen bezeichnet. Später werden Sie mehr darüber erfahren. 7.2.2 Parameterbehaftete Eigenschaften
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| myObject.TheProperty[2] = 10; |
der Eigenschaftswert festgelegt werden kann.
Parametrisierte Eigenschaften sind von Bedeutung, wenn Randbedingungen den von der Eigenschaft beschriebenen Wert beeinflussen. In der fiktiven Eigenschaft TheProperty lautet die Randbedingung »2«. Unter dieser Prämisse soll der Eigenschaft die Zahl 10 zugewiesen werden. Der Code ähnelt ohne Zweifel einem Array und lässt sich auch so interpretieren: Es handelt sich um eine indizierte Sammlung gleichnamiger Eigenschaftselemente.
Wir wollen uns jetzt ansehen, wie in einer Klasse eine parameterbehaftete Eigenschaft realisiert werden kann. Dazu stellen wir uns eine Klasse Car mit einer Eigenschaft Color vor. Ein Car-Objekt beschreibt das Auto eines beliebigen Herstellers. Wir wissen alle, dass die verschiedenen Autoproduzenten unterschiedliche Farbpaletten anbieten – oft modellabhängig. Einen Ferrari gibt es möglicherweise nur in Rot, Gelb oder Schwarz, kaufen Sie einen häufiger vertretenen Typ, können Sie vielleicht unter 20 verschiedenen Farben auswählen. Diese Situation soll die Eigenschaft Color der Car-Klasse beschreiben.
Der Eigenschaft Color wollen wir als Argument eine Zeichenfolge übergeben, die den Hersteller beschreibt. Zurückgeliefert wird daraufhin die Palette der zur Auswahl stehenden Farben. Ein Aufruf könnte dann wie folgt aussehen:
| int[] colors = myCar.Color["Mazda"]; |
Dies sei unser Ziel. Widmen wir uns nun dem Code. Der Teilausdruck
| Color["Mazda"] |
lässt sich über einen Indexer realisieren. Ein Indexer setzt ein Objekt voraus, denn wie wir wissen, überladen wir den »[]«-Operator in this, dem aktuellen Objekt also. Daraus kann gefolgert werden, dass wir zusätzlich zur Klasse Car eine zweite Klasse definieren müssen, die ihrerseits die Eigenschaft beschreibt. Im Folgenden soll der Name dieser Klasse CarColor lauten.
Wir könnten nun beide Klassen mit
| public class Car {/*...*/} |
| public class CarColor {/*...*/} |
festlegen, aber damit käme die eindeutige Zugehörigkeit von CarColor zu Car nicht zum Ausdruck, weil CarColor auch ohne ein zugrunde liegendes Car-Objekt instanziiert werden könnte. Wir wissen aber, dass CarColor in einer direkten Beziehung zu Car steht. Deshalb drängt sich geradezu die Idee auf, CarColor in Car zu verschachteln:
| public class Car { |
| public class CarColor {/*...*/} |
| } |
Ein Objekt vom Typ CarColor soll einem Benutzer als schreibgeschützte Eigenschaft eines Car-Objekts angeboten werden. Wir ergänzen deshalb die äußere Klassendefinition Car um ein Feld, das die Referenz auf ein Car-Objekt zurückliefert:
| public class Car { |
| public readonly CarColor Color = new CarColor(); |
| public class CarColor {/*...*/} |
| } |
Abgesehen von der internen Implementierung der Klasse CarColor können wir Car als fertig betrachten. Der gesamte weitere Programmcode beruht auf der vereinfachenden Annahme, dass sich die von jedem Hersteller angebotene Farbpalette nicht ändert. In der Praxis würde man diese im Car-Konstruktor vermutlich aus einer Datenbank beziehen. Wir legen die Farben jedoch in der Klasse CarColor fest, denn zum Verständnis des Einsatzes der Indexer im Zusammenhang mit parameterbehafteten Eigenschaften ist das völlig ausreichend.
Aus Sicht eines Benutzers sind wir nun an dieser Stelle angelangt:
| Car myCar = new Car(); |
| myCar.Color |
Die zweite, noch unvollständige Anweisung liefert die Referenz auf ein CarColor-Objekt zurück. Jetzt schlägt die Stunde der Indexer! Zur Vervollständigung der Aufrufsyntax mit dem »[]«-Operator müssen wir im nächsten Schritt in CarColor einen Indexer codieren.
Auch hier vereinfachen wir die Situation und tun so, als würde es nur zwei Autohersteller geben. Beim Aufruf der Color-Eigenschaft wird als Zeichenfolge der Hersteller übergeben, der Rückgabewert sei ein Integer-Array, in dem jede Zahl für eine bestimmte Farbe steht.
| public class CarColor { |
| public int[] this[string hersteller] { |
| get { |
| switch(hersteller) { |
| case "Rover": |
| return new int[]{2, 3, 4, 5}; |
| case "Mazda": |
| return new int[]{1, 2, 5, 6}; |
| default: |
| return new int[]{0}; |
| } |
| } |
| } |
| } |
Der Indexer versetzt uns jetzt in die Lage, beim Aufruf der Eigenschaft Color einen Index anzugeben, der als Argument interpretiert wird und den Eigenschaftswert maßgeblich beeinflusst.
Fassen wir den gesamten Code zusammen und schreiben dazu noch einen Testcode, der exakt die Anweisung enthält, die Ausgangspunkt unserer Überlegungen war.
| // -------------------------------------------------------------- |
| // Beispiel: ...\Kapitel 7\Eigenschaftsparameter |
| // -------------------------------------------------------------- |
| class Program { |
| static string[] color = new string[]{"Fehleingabe", "weiss","blau","gelb","rot","schwarz","lila"}; |
| static void Main(string[] args) { |
| Car myCar = new Car(); |
| int[] arrInt = myCar.Color["Mazda"]; |
| for(int i = 0; i < arrInt.Length; i++) |
| Console.WriteLine("Farbe {0} = {1}", i, color[arrInt[i]] ); |
| Console.ReadLine(); |
| } |
| } |
| public class Car { |
| public readonly CarColor Color = new CarColor(); |
| public class CarColor { |
| // Indexer |
| public int[] this[string hersteller] { |
| get { |
| switch(hersteller) { |
| case "Rover": |
| return new int[]{2, 3, 4, 5}; |
| case "Mazda": |
| return new int[]{1, 2, 5, 6}; |
| default: |
| return new int[]{0}; |
| } |
| } |
| } |
| } |
| } |
Jede der beim Aufruf der Eigenschaft Color zurückgelieferten Integerzahlen ist demselben numerischen Index im string-Array der Testklasse zugeordnet. Die einzige Ausnahme bildet der Index 0, der eine unzulässige Parameterübergabe an die Eigenschaft signalisiert. Mit
| int[] arrInt = myCar.Color["Mazda"]; |
weisen wir den Rückgabewert einem Array zu, das in der darauf folgenden for-Schleife durchlaufen wird und die herstellerspezifische Farbpalette im Befehlsfenster ausgibt.
| << zurück |
|
||||||||||||||
|
||||||||||||||
|
||||||||||||||
|
||||||||||||||
Copyright © Galileo Press 2006
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.